from sqlalchemy import func
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import func
from sqlalchemy.dialects.postgresql import JSONB
from models.engine import db
from sqlalchemy.ext.mutable import MutableDict
from models.robot.intent_reco import RobFuncs
from models.robot.rob_charater import RobCharacter
from models.robot.rob_emoji import RobEmojiPack
from models.robot.rob_timbre import RobTimbre
from models.types import StringUUID



class RobFunDomainMap(db.Model):
    __tablename__ = "rob_fun_domain_map"
    __table_args__ = (
        db.PrimaryKeyConstraint('func_id','domain_id',name='idx_rob_fun_domain_map_pk'),
        db.Index('idx_rob_fun_domain_map_domain', 'domain_id'),
    )
    domain_id = db.Column(StringUUID, nullable=False,comment="域ID")
    func_id = db.Column(StringUUID, nullable=False,comment="函数ID")

class RobFunDomain(db.Model):
    __tablename__ = "rob_fun_domain"
    __table_args__ = (db.PrimaryKeyConstraint("id", name="rob_fun_domain_pkey"),
                      db.Index("rob_fun_domain_tenant_idx", "tenant_id"))
    id: Mapped[str] = mapped_column(
        StringUUID, server_default=db.text("uuid_generate_v4()"),)
    tenant_id = db.Column(StringUUID, nullable=False,comment="租户ID")
    name = db.Column(db.String(128), nullable=False,comment="名称")
    descrip = db.Column(db.String(512), nullable=False,comment="说明描述")
    default_character_id = db.Column(StringUUID, nullable=True,)
    default_timbre_id = db.Column(StringUUID, nullable=True,)
    default_emoji_pack_id = db.Column(StringUUID, nullable=True,)
    config = db.Column(MutableDict.as_mutable(JSONB), nullable=True,server_default=db.text('{}'),comment="配置")
    price = db.Column(db.Integer, nullable=False,default=0,comment="价格/分")
    period = db.Column(db.Integer, nullable=False,default=-1,comment="有效期：-1永久")
    period_unit = db.Column(db.Integer, nullable=False,default=-1,comment="周期单位:周期单位：1天，2：月，3，几度，4年")
    created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp(),comment="创建时间")
    created_by = db.Column(StringUUID, nullable=False,comment="创建人")
    updated_at = db.Column(db.DateTime, nullable=True, server_default=func.current_timestamp())
    updated_by = db.Column(StringUUID, nullable=True,)
    @property
    def funcs(self) -> list[RobFuncs]:
        return db.session.query(RobFuncs).join(RobFunDomainMap,RobFunDomainMap.func_id==RobFuncs.id).filter(RobFunDomainMap.domain_id==self.id).all()
    
    def to_dict(self)->dict:
        return {
            "id":self.id,
            "name":self.name,
            "descrip":self.descrip,
            "funcs":[func.to_dict() for func in self.funcs] if self.funcs else []
        }
    # @property
    # def characters(self)->list[RobCharacter]:
    #     if self.config:
    #         character_ids = self.config.get("characters",[])
    #         return db.session.query(RobCharacter).filter(RobCharacter.id.in_(character_ids)).all()
    #     return []
    
    # @characters.setter
    # def characters(self,characters:list[RobCharacter]):
    #     if self.config:
    #         self.config["characters"] = [str(character.id) for character in characters]
    #     else:
    #         self.config = {"characters":[character.id for character in characters]}
    

    @property
    def characters(self)->list[RobCharacter]:
        if self.config:
            character_ids = self.config.get("characters",[])
            return db.session.query(RobCharacter).filter(RobCharacter.id.in_(character_ids)).all()
        return []
    
    @characters.setter
    def characters(self,characters:list[RobCharacter]):
        if self.config:
            chara_ids = self.config.get("characters",[])
            new_ids = [str(character.id) for character in characters]
            chara_ids = list(set(chara_ids) | set(new_ids))
            self.config["characters"] = chara_ids
        else:
            self.config = {"characters":[character.id for character in characters]}
        timbre_ids = [str(character.default_timbre_id) for character in characters if character.default_timbre_id]
        exit_timbre_ids = self.config.get("timbres",[])
        timbre_ids = list(set(timbre_ids)|set(exit_timbre_ids))
        self.config["timbres"] = timbre_ids

        emoji_pack_ids = [str(character.default_emoji_pack_id)for character in characters if character.default_emoji_pack_id]
        exist_emoji_pack_ids = self.config.get("emoji_packs",[])
        emoji_pack_ids = list(set(emoji_pack_ids)|set(exist_emoji_pack_ids))
        self.config["emoji_packs"] = emoji_pack_ids

    
    @property
    def timbres(self)->list[RobTimbre]:
        if self.config:
            timbre_ids = self.config.get("timbres",[])
            return db.session.query(RobTimbre).filter(RobTimbre.id.in_(timbre_ids)).all()
        return []
    
    @timbres.setter
    def timbres(self,timbres:list[str]):
        if self.config:
            timbre_ids = self.config.get("timbres",[])
            # new_ids = [str(timbre.id) for timbre in timbres]
            timbre_ids = list(set(timbre_ids)|set(timbres))
            self.config["timbres"] = timbre_ids
        else:
            self.config = {"timbres": timbres}#[str(timbre.id) for timbre in timbres]}
    
    @property
    def emoji_packs(self)->list[RobEmojiPack]:
        if self.config:
            emoji_pack_ids = self.config.get("emoji_packs",[])
            return db.session.query(RobEmojiPack).filter(RobEmojiPack.id.in_(emoji_pack_ids)).all()
        return []
    
    @emoji_packs.setter
    def emoji_packs(self,emoji_packs:list[str]):
        if self.config:
            emoji_ids = self.config.get("emoji_packs",[])
            # new_ids = [str(emoji_pack.id) for emoji_pack in emoji_packs]
            emoji_ids = list(set(emoji_packs)|set(emoji_ids))
            self.config["emoji_packs"] = emoji_ids
        else:
            self.config = {"emoji_packs": emoji_packs}#[str(emoji_pack.id) for emoji_pack in emoji_packs]}

    @property
    def Price(self)->float:
        if self.price:
            return self.price*(1.0/1000.0)
        return 0.0
    
    